//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.Generic;
using System.Text;
using ER = Microsoft.Research.DataLayer;

namespace Microsoft.Research.DataLayer
{
    /// <summary>
    /// 
    /// </summary>
    public interface ISearchClause
    {
    }

    /// <summary>
    /// Internal implementation of search clause
    /// </summary>
    public interface ISearchClauseImpl
    {
        /// <summary>
        /// Name of the field
        /// </summary>
        string Name { get; }

        /// <summary>
        /// Comparison operation
        /// </summary>
        Enum Op { get; }

        /// <summary>
        /// Value to compare
        /// </summary>
        object Value { get; set; }

   }

    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    public class SearchClause : ISearchClause, ISearchClauseImpl
    {
        private string name;
        private Enum op;
        private object val;
        
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name"></param>
        /// <param name="operation"></param>
        /// <param name="value"></param>
        public SearchClause(string name, Enum operation, object value)
        {
            this.name = name;
            this.op = operation;
            this.val = value;            
        }

        #region ISearchClause Members

        /// <summary>
        /// Return the field name
        /// </summary>
        public string Name
        {
            get { return name; }
        }

        /// <summary>
        /// Comparison operation against value
        /// </summary>
        public Enum Op
        {
            get { return op; }
        }

        /// <summary>
        /// Value to compare to
        /// </summary>
        public object Value
        {
            get { return val; }
            set { val = value; }
        }

        #endregion
    }

    /// <summary>
    /// Wrapper object to ensure correct type casts
    /// </summary>
    [Serializable]
    public abstract class SearchClauseWrapper
    {
        private ER.ISearchClause clause;
        private ER.BaseField field;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="field"></param>
        /// <param name="clause"></param>
        protected SearchClauseWrapper(ER.BaseField field, ER.ISearchClause clause)
        {
            this.field = field;
            this.clause = clause;
        }

        #region ISearchClause Members

        /// <summary>
        /// 
        /// </summary>
        public ER.ISearchClause Clause
        {
            get { return clause; }
        }

        /// <summary>
        /// 
        /// </summary>
        public ER.ISearchClauseImpl ClauseImpl
        {
            get { return clause as ISearchClauseImpl; }
        }

        /// <summary>
        /// 
        /// </summary>
        public ER.BaseField Field
        {
            get { return field; }
            set { field = value; }
        }

        #endregion
    }

    /// <summary>
    /// Predicate join options
    /// </summary>
    public enum SearchRelUnary
    {
        /// <summary>
        /// NOT
        /// </summary>
        Not,
    }

    /// <summary>
    /// Predicate join options
    /// </summary>
    public enum SearchRelBinary
    {
        /// <summary>
        /// AND
        /// </summary>
        And,

        /// <summary>
        /// OR
        /// </summary>
        Or,
    }
}
